package com.plian.system.excel;

import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.DateUtil;
import com.plian.Tools.StringUtil;
import com.plian.system.mybatis.base.BaseEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @description:
 * @author: gangan
 * @create: 2020-03-16 14:48
 */
public class ImportExcelUtil {
    private static final Logger log = LoggerFactory.getLogger(ImportExcelUtil.class);
//    private static IMetaObjectRefClient metaObjectRefClient = (IMetaObjectRefClient)SpringUtil.getBean(IMetaObjectRefClient.class);
//    private static IDictClient dictClient = (IDictClient)SpringUtil.getBean(IDictClient.class);
    public static final String DUP_MSG = "重复!";
    public static final String EXISTED_MSG = "已存在!";
    private static final String OBJECT_MSG = "未找到对应对象!";
    private static final String DICT_MSG = "未找到对应字典!";
    private static final String SWITCH_MSG = "填写错误，请填写01或02（分别对应否和是）!";
    private static final String INTEGER_MSG = "格式错误,应为整数!";
    private static final String BIGDECIMAL_MSG = "格式错误,应为浮点数!";
    private static final String DATE_MSG = "格式错误,应为yyyy-MM-dd!";
    private static final String REQUIRED_MSG = "应为必填!";
    public static final String TYPE_INTEGER = "Integer";
    public static final String TYPE_BIGDECIMAL = "BigDecimal";
    public static final String TYPE_DATE = "Date";
    public static final String TYPE_DATE_TWO="Date_two";
    public static final String TYPE_DATE_MONTH = "DateMonth";
    private static final String INTEGER_PATTERN = "^[+-]?[0-9]+$";
    private static final String BIGDECIMAL_PATTERN = "([0-9]\\d*\\.?\\d*)|((-)?[0-9]\\d*\\.?\\d*)";
    private static final String DATE_PATTERN = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)";

    public ImportExcelUtil() {
    }



    public static ImportResult isExisted(String sheetNo, String key, String columnName, List<String> columnList, List<Object> entityList) {
        List<String> repeatValueList = findRepeat(columnList);
        StringBuilder msg = new StringBuilder();
        Iterator var7 = repeatValueList.iterator();

        while(var7.hasNext()) {
            String value = (String)var7.next();
            List<Integer> intList = new ArrayList();

            for(int i = 0; i < columnList.size(); ++i) {
                if (columnList.get(i) != null && ((String)columnList.get(i)).equals(value)) {
                    intList.add(i + 2);
                }
            }

            msg.append(msgBuilder(sheetNo, intList.toString(), columnName, value, "重复!"));
        }

        Map<String, Object> entityMap = new HashMap(16);
        Iterator var12 = beanList2MapList(entityList).iterator();

        while(var12.hasNext()) {
            Map<String, Object> map = (Map)var12.next();
            if (Optional.ofNullable(map.get(key)).isPresent()) {
                entityMap.put(map.get(key).toString(), map);
            }
        }

        var12 = columnList.iterator();

        while(var12.hasNext()) {
            String column = (String)var12.next();
            if (entityMap.containsKey(column)) {
                msg.append(msgBuilder(sheetNo, String.valueOf(columnList.indexOf(column) + 2), columnName, column, "已存在!"));
            }
        }

        if (msg.length() > 0) {
            return new ImportResult(false, msg.toString());
        } else {
            return new ImportResult(true, "");
        }
    }

    public static ImportResult checkEmpty(String sheetNo, String columnName, String value, int index) {
        StringBuilder msg = new StringBuilder();
        if (!StringUtil.isEmpty(value) && !StringUtil.isEmpty(value.trim())) {
            return new ImportResult(true, "");
        } else {
            msg.append(msgBuilder(sheetNo, String.valueOf(index + 2), columnName, value, "应为必填!"));
            return new ImportResult(false, msg.toString());
        }
    }

    //不填(债务项目情况)
    public static ImportResult checkNull(String sheetNo, String columnName, String value, int index) {
        StringBuilder msg = new StringBuilder();
        if (StringUtil.isEmpty(value) || StringUtil.isEmpty(value.trim())) {
            return new ImportResult(true, "");
        } else {
            msg.append(msgBuilder(sheetNo, String.valueOf(index + 2), columnName, value, ",应不填!(是否基金投资为2是的时候)"));
            return new ImportResult(false, msg.toString());
        }
    }




    public static ImportResult checkSwitch(String sheetNo, String columnName, String value, int index) {
        ImportResult importResult = new ImportResult(true, "");
        StringBuilder msg = new StringBuilder();
        if (StringUtil.isEmpty(value)) {
            return importResult;
        } else {
            if (Integer.valueOf(value) != 1 && Integer.valueOf(value) != 2) {
                msg.append(msgBuilder(sheetNo, String.valueOf(index + 2), columnName, value, "填写错误，请填写01或02（分别对应否和是）!"));
            }

            return msg.length() > 0 ? new ImportResult(false, msg.toString()) : new ImportResult(true, "");
        }
    }

    public static ImportResult checkType(String convertType, String sheetNo, String columnName, String value, int index) {
        ImportResult importResult = new ImportResult(true, "");
        StringBuilder msg = new StringBuilder();
        if (StringUtil.isEmpty(value)) {
            return importResult;
        } else {
            byte var8 = -1;
            if ("Integer".equals(convertType)) {
                var8 = 0;
            }else  if ("Date".equals(convertType)) {
                var8 = 2;
            }else if ("BigDecimal".equals(convertType)) {
                var8 = 1;
            }else if ("DateMonth".equals(convertType)) {
                var8 = 3;
            }else  if ("Date_two".equals(convertType)) {
                var8 = 4;
            }

            switch(var8) {
                case 0:
                    if (!Pattern.matches("^[+-]?[0-9]+$", value)) {
                        msg.append(msgBuilder(sheetNo, String.valueOf(index + 2), columnName, value, "格式错误,应为整数!"));
                    }
                    break;
                case 1:
                    if (!Pattern.matches("([0-9]\\d*\\.?\\d*)|((-)?[0-9]\\d*\\.?\\d*)", value)) {
                        msg.append(msgBuilder(sheetNo, String.valueOf(index + 2), columnName, value, "格式错误,应为浮点数!"));
                    }
                    break;
                case 2:
                    if (!Pattern.matches("(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)", value)) {
                        msg.append(msgBuilder(sheetNo, String.valueOf(index + 2), columnName, value, "格式错误,应为yyyy-MM-dd!"));
                    }
                    break;
                case 3:
                    if (!Pattern.matches("^([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-([0][0-9]|[1][0-2])$", value)) {
                        msg.append(msgBuilder(sheetNo, String.valueOf(index + 2), columnName, value, "格式错误,应为yyyy-MM!"));
                    }
                    break;
                case 4:
                    if (!Pattern.matches("^\\d{4}\\.(0[1-9]|1[0-2])\\.(0[1-9]|[12][0-9]|3[01])$", value)) {
                        msg.append(msgBuilder(sheetNo, String.valueOf(index + 2), columnName, value, "格式错误,应为yyyy.MM.dd!"));
                    }
                    break;
                default:
                    break;
            }

            return msg.length() > 0 ? new ImportResult(false, msg.toString()) : new ImportResult(true, "");
        }
    }

    public static String msgBuilder(String sheetNo, String lineNo, String columnName, String value, String errMsg) {
        return "sheet" + sheetNo + "第" + lineNo + "行(" + columnName + "=" + value + ")" + errMsg + System.getProperty("line.separator");
    }

    public static List<Map<String, Object>> beanList2MapList(List<Object> objectList) {
        List<Map<String, Object>> mapList = new ArrayList();
        Iterator var2 = objectList.iterator();

        while(var2.hasNext()) {
            Object object = var2.next();
            mapList.add(BeanUtils.beanToMap(object));
        }

        return mapList;
    }

    public static <T> List<T> findRepeat(Collection<T> datas) {
        if (datas instanceof Set) {
            return new ArrayList();
        } else {
            HashSet<T> set = new HashSet();
            List<T> repeatEles = new ArrayList();
            Iterator var3 = datas.iterator();

            while(var3.hasNext()) {
                T t = (T)var3.next();
                if (set.contains(t)) {
                    repeatEles.add(t);
                } else {
                    set.add(t);
                }
            }

            return distinct(repeatEles);
        }
    }

    public static <T> List<T> distinct(Collection<T> datas) {
        if (datas == null) {
            return new ArrayList();
        } else {
            Set<T> set = new HashSet(datas);
            return new ArrayList(set);
        }
    }

    public static BaseEntity getEntityByExcelBean(Object excelBean, BaseEntity entity) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, ParseException {
        Field[] fields = excelBean.getClass().getDeclaredFields();
        Field[] var3 = fields;
        int var4 = fields.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            Field field = var3[var5];
            String name = field.getName();
            String upperCaseName = name.substring(0, 1).toUpperCase() + name.substring(1);
            String type = null;

            try {
                type = String.valueOf(entity.getClass().getDeclaredField(name).getGenericType());
            } catch (NoSuchFieldException var12) {
                var12.printStackTrace();
            }

            if (Optional.ofNullable(excelBean.getClass().getMethod("get" + upperCaseName).invoke(excelBean)).isPresent()) {
                if ("class java.lang.String".equals(type)) {
                    String value = (String)excelBean.getClass().getMethod("get" + upperCaseName).invoke(excelBean);
                    entity.getClass().getMethod("set" + upperCaseName, String.class).invoke(entity, value);
                }

                if ("class java.lang.Integer".equals(type)) {
                    Integer value = Integer.valueOf(excelBean.getClass().getMethod("get" + upperCaseName).invoke(excelBean).toString());
                    entity.getClass().getMethod("set" + upperCaseName, Integer.class).invoke(entity, value);
                }

                if ("class java.lang.Long".equals(type)) {
                    Long value = Long.valueOf(excelBean.getClass().getMethod("get" + upperCaseName).invoke(excelBean).toString());
                    entity.getClass().getMethod("set" + upperCaseName, Long.class).invoke(entity, value);
                }

                if ("class java.math.BigDecimal".equals(type)) {
                    BigDecimal value = new BigDecimal(excelBean.getClass().getMethod("get" + upperCaseName).invoke(excelBean).toString());
                    entity.getClass().getMethod("set" + upperCaseName, BigDecimal.class).invoke(entity, value);
                }

                if ("class java.util.Date".equals(type)) {
                    String dateStr = excelBean.getClass().getMethod("get" + upperCaseName).invoke(excelBean).toString();
                    String datePattern = "";
                    if (Pattern.matches("^([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-([0][0-9]|[1][0-2])$", dateStr)) {
                        datePattern = DateUtil.PATTERN_MONTH;
                    }else {
                        datePattern = DateUtil.PATTERN_DATE;
                    }
                    SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
                    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+08"));
                    Date value = dateFormat.parse(excelBean.getClass().getMethod("get" + upperCaseName).invoke(excelBean).toString());
                    entity.getClass().getMethod("set" + upperCaseName, Date.class).invoke(entity, value);
                }
            }
        }

        return entity;
    }

    /**
     * 判断该对象是否: 返回ture表示所有属性为null  返回false表示不是所有属性都是null
     * @param obj
     * @return
     * @throws IllegalAccessException
     */
    public static boolean isAllFieldNull(Object obj) throws IllegalAccessException {
        Class<?> aClass = obj.getClass();
        Field[] fs = aClass.getDeclaredFields();
        boolean flag=true;
        for (Field f : fs) {
            f.setAccessible(true);
            Object o = f.get(obj);
            if (o!=null){
                if (o instanceof String){
                    if (StringUtil.isNotBlank((String)o)){
                        flag = false;
                    }
                }else {
                    flag=false;
                }

            }
        }
        return flag;
    }

    /**
     * 遍历list  删除所有属性为空的对象
     * @param objects
     * @throws IllegalAccessException
     */
    public static void filterEmpty(List<Object> objects) throws IllegalAccessException{
        if (CollectionUtil.isEmpty(objects)){
            return;
        }
        //遍历删除,除去空类
        Iterator<Object> iterator = objects.iterator();
        while (iterator.hasNext()) {
            Object obj = iterator.next();
            if (isAllFieldNull(obj)) {
                iterator.remove();//使用迭代器的删除方法删除
            }
        }
    }
}
